package com.xhj.mybatis.executor.statement;

import com.xhj.mybatis.executor.Executor;
import com.xhj.mybatis.executor.keygen.Jdbc3KeyGenerator;
import com.xhj.mybatis.executor.keygen.KeyGenerator;
import com.xhj.mybatis.mapping.BoundSql;
import com.xhj.mybatis.mapping.MappedStatement;
import com.xhj.mybatis.session.ResultHandler;
import com.xhj.mybatis.session.RowBounds;

import java.sql.*;
import java.util.List;

/**
 * PreparedStatementHandler
 *
 * @author XJks
 * @description 预处理语句处理器，专门用于处理 JDBC 的 PreparedStatement
 */
public class PreparedStatementHandler extends BaseStatementHandler {

    public PreparedStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
        super(executor, mappedStatement, parameter, rowBounds, resultHandler, boundSql);
    }

    /**
     * 用于执行更新操作（如 INSERT、UPDATE、DELETE）
     *
     * @param statement 要执行的 Statement 对象
     * @return 受影响的行数
     * @throws SQLException SQL 异常
     */
    @Override
    public int update(Statement statement) throws SQLException {
        // 将 Statement 强制转换为 PreparedStatement
        PreparedStatement ps = (PreparedStatement) statement;
        // 执行 SQL 语句
        ps.execute();
        // 获取受影响的行数
        int rows = ps.getUpdateCount();
        // 获取参数对象
        Object parameterObject = boundSql.getParameterObject();
        // 获取主键生成器
        KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();
        // 执行主键生成器的后置处理（如获取自增主键）
        keyGenerator.processAfter(executor, mappedStatement, ps, parameterObject);
        // 返回受影响的行数
        return rows;
    }

    /**
     * 执行查询并返回结果列表
     *
     * @param statement     要执行的 Statement 对象
     * @param resultHandler 结果处理器
     * @param <E>           结果类型的泛型
     * @return 结果列表
     * @throws SQLException SQL 异常
     */
    @Override
    public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {
        // 将 Statement 强制转换为 PreparedStatement
        PreparedStatement ps = (PreparedStatement) statement;
        // 执行 SQL 查询
        ps.execute();
        // 处理结果集并返回结果列表
        return resultSetHandler.handleResultSets(ps);
    }

    /**
     * 创建并返回一个 PreparedStatement 对象
     *
     * @param connection 数据库连接对象，用于创建 Statement
     * @return PreparedStatement 对象
     * @throws SQLException SQL 异常
     */
    @Override
    protected Statement instantiateStatement(Connection connection) throws SQLException {
        // 获取 SQL 语句
        String sql = boundSql.getSql();
        // 判断是否使用 Jdbc3KeyGenerator（用于获取自增主键）
        if (mappedStatement.getKeyGenerator() instanceof Jdbc3KeyGenerator) {
            // 获取主键列名
            String[] keyColumnNames = mappedStatement.getKeyColumns();
            if (keyColumnNames == null) {
                // TODO:如果没有指定主键列名，使用 RETURN_GENERATED_KEYS
                return connection.prepareStatement(sql, PreparedStatement.RETURN_GENERATED_KEYS);
            } else {
                // 如果指定了主键列名，传递列名参数
                return connection.prepareStatement(sql, keyColumnNames);
            }
        } else {
            // todo:源码这里还有其他处理逻辑，暂不实现，直接创建普通的 PreparedStatement
            return connection.prepareStatement(sql);
        }
    }

    /**
     * 为 PreparedStatement 设置参数
     *
     * @param statement 要设置参数的 Statement 对象
     * @throws SQLException SQL 异常
     */
    @Override
    public void parameterize(Statement statement) throws SQLException {
        // 调用参数处理器为 PreparedStatement 设置参数
        parameterHandler.setParameters((PreparedStatement) statement);
    }

}
